package com.hxexp.weixin.mvc.order.controller;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.joda.time.Hours;
import org.joda.time.LocalDateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hxexp.weixin.common.cache.PassengerTicketCacheManager;
import com.hxexp.weixin.common.cache.TokenCacheManager;
import com.hxexp.weixin.common.cache.model.PassengerTicketInfo;
import com.hxexp.weixin.common.exception.ServiceException;
import com.hxexp.weixin.constant.CarryFreeTicketFlag;
import com.hxexp.weixin.constant.ChannelType;
import com.hxexp.weixin.constant.CookieName;
import com.hxexp.weixin.constant.Errcode;
import com.hxexp.weixin.constant.HasTicketPassengerInfo;
import com.hxexp.weixin.constant.IdentificationType;
import com.hxexp.weixin.constant.LineType;
import com.hxexp.weixin.constant.OrderStatus;
import com.hxexp.weixin.constant.PassengerType;
import com.hxexp.weixin.constant.PriceType;
import com.hxexp.weixin.constant.Privilege;
import com.hxexp.weixin.constant.ReferType;
import com.hxexp.weixin.constant.StartStationsId;
import com.hxexp.weixin.constant.StringConstant;
import com.hxexp.weixin.constant.TicketState;
import com.hxexp.weixin.constant.TicketType;
import com.hxexp.weixin.constant.TrafficlineNC;
import com.hxexp.weixin.constant.WebAppVersion;
import com.hxexp.weixin.hpe.api.login.model.LoginResultBean;
import com.hxexp.weixin.hpe.api.orderdetail.model.OrderDetailResultBean;
import com.hxexp.weixin.hpe.api.orderdetail.model.OrderTicketInfoBean;
import com.hxexp.weixin.hpe.api.ordersubmit.model.OrderSubmitBean;
import com.hxexp.weixin.hpe.api.ordersubmit.model.OrderSubmitParamBean;
import com.hxexp.weixin.hpe.api.ordersubmit.model.OrderSubmitResultBean;
import com.hxexp.weixin.hpe.api.userorderlist.model.OrderInfoBean;
import com.hxexp.weixin.hpe.api.userorderlist.model.TicketInfoBean;
import com.hxexp.weixin.hpe.api.userorderlist.model.UserOrderListResultBean;
import com.hxexp.weixin.mvc.common.service.CommonSerivce;
import com.hxexp.weixin.mvc.common.service.TicketTypeService;
import com.hxexp.weixin.mvc.order.model.OrderConfirmInfoBean;
import com.hxexp.weixin.mvc.order.service.OrderService;

import net.sf.cglib.beans.BeanCopier;

/**
 * 订单控制器
 *
 * @author li.jiang
 * @author wang.bin
 */
@Controller
@RequestMapping(value = "/order")
public final class OrderController {
    private static final Logger LOGGER = LoggerFactory.getLogger(OrderController.class);
    private static final int PAGE_SIZE = 6;
    private static final String PRIVILEGE_ATTR = "hasPrivilege";
    private static final String DECIMAL_PATTERN = "#0.00";
    private static final String KEY_FULLTICKETNUM = "fullTicketNum";
    private static final String KEY_HALFTICKETNUM = "halfTicketNum";
    private static final String KEY_FREETICKETNUM = "freeTicketNum";
    private static final String KEY_PASSENGERNUM = "passengerNum";
    private static final String KEY_REFUNDNUM = "refundNum";
    private static final String KEY_TOTALSERVICEPRICE = "totalServicePrice";
    private static final String HASPASSENGERINFO_ATTR = "haspassengerinfo";
    private static final String ZERO_DOUBLE = "0.00";
    private static final String TOTAL_PRIVILEGE_AMOUNT_ATTR = "totalPrivilegeAmount";
    private static final String REFER_ATTR = "refer";
    private static final String STARTSTATIONID_ATTR = "startstationid";
    private static final String PAGENOW_ATTR = "pageNow";
    private static final String TICKETQUERYURL_ATTR = "ticketQueryURL";

    private static final String KEY_TOTALINSURANCE = "totalInsurance"; // NOSONAR

    private static final String HASINSURANCE_ATTR = "1";
    // private static final String PRIVILEGE_INSURANCE = "5.00";

    private static final String NCSTARTSTATION_ATTR = "hasNcStartStation";

    private BeanCopier beanCopier1 = BeanCopier.create(OrderDetailResultBean.class, PassengerTicketInfo.class, false);
    private BeanCopier beanCopier2 = BeanCopier.create(OrderTicketInfoBean.class, PassengerTicketInfo.class, false);
    private BeanCopier beanCopier3 = BeanCopier.create(OrderConfirmInfoBean.class, OrderSubmitParamBean.class, false);

    @Autowired
    private OrderService orderService;
    @Autowired
    private TokenCacheManager tokenCacheManager;
    @Autowired
    private PassengerTicketCacheManager pticketCacheManager;
    @Autowired
    private CommonSerivce commonSerivce;
    @Autowired
    private TicketTypeService ticketTypeService;
    /**
     * 设置页面需要的常量
     *
     * @return
     */
    @ModelAttribute("constant")
    public Map<String, String> setConstant() {
        Map<String, String> map = new HashMap<String, String>();
        map.put("priceType_full", PriceType.FULL); // 票价类别：全价
        map.put("priceType_half", PriceType.HALF); // 票价类别：半价

        map.put("has_passenginfo", HasTicketPassengerInfo.HAS_PASSENGERINFO); // 车票包含乘客信息
        map.put("no_passenginfo", HasTicketPassengerInfo.NO_PASSENGERINFO); // 车票不包含乘客信息
        map.put("order_status_unpaid", OrderStatus.UNPAID); // 订单状态：未支付
        map.put("order_status_paid", OrderStatus.PAID); // 订单状态：已支付
        map.put("order_status_boundpassenger", OrderStatus.BOUND_PASSENGER); // 订单状态：已绑定乘客
        map.put("order_status_booking", OrderStatus.BOOKING); // 订单状态：已预定
        // 设置车票状态信息
        map.put("ticketed_fail", TicketState.TICKETED_FAIL);// 出票失败
        map.put("refunded", TicketState.REFUNDED);// 已退票
        map.put("ticket_success", TicketState.TICKETED_SUCCESS);// 已出票
        map.put("initialize", TicketState.INITIALIZE);// 初始状态
        map.put("collected_ticket", TicketState.COLLECTED_TICKET);// 取票
        map.put("refunded_rebate_fail", TicketState.REFUNDED_REBATE_FAIL);// 退款失败
        map.put("refunded_rebating", TicketState.REFUNDED_REBATING);// 退款中

        map.put("refer_ordersubmit", ReferType.REFER_ORDERCONFIRM);// 来源于确认订单页面
        map.put("refer_orderdetail", ReferType.REFER_ORDERDETAIL);// 来源于订单详情页面

        map.put("appver_nc", WebAppVersion.NC);// 南充当代运业网站版本编号
        map.put("appver_lz", WebAppVersion.LZ);// 泸州中心站站网站版本编号
        map.put("appver_hx", WebAppVersion.HX);// 华夏快线网站版本编号
        map.put("appver_xy", WebAppVersion.XY);// 叙永汽车站
        map.put("appver_ylns", WebAppVersion.YLNS); // 四川仪陇农商银行

        map.put("groupId_nc", TrafficlineNC.GROUP_ID);
        map.put("carry", CarryFreeTicketFlag.CARRY);// 携带免票

        map.put("idcard", IdentificationType.IDCARD);// 身份证

        map.put("lxzx_startstation_id", StartStationsId.LXZX);// 泸县中心站ID
        map.put("lzzx_startstation_id", StartStationsId.LZZX);// 泸州中心站ID
        map.put("nbcx_startstation_id", StartStationsId.NBCX);// 南部城西客运站ID
        map.put("ncmsp_startstation_id", StartStationsId.NCMSP);// 南充马市铺客运站ID
        map.put("xccx_startstation_id", StartStationsId.XCCX);// 西充县城西客运站ID
        map.put("ylccx_startstation_id", StartStationsId.YLCCX);// 仪陇超长客运站ID
        map.put("lzxy_startstation_id", StartStationsId.LZXY);// 叙永汽车站ID
        map.put("ay_startstation_id", StartStationsId.AY); // 安岳客运总站ID
        map.put("xa_startstation_id", StartStationsId.XA); // 陕西省西安汽车站编码
        map.put("xawsl_startstation_id", StartStationsId.XAWSL);// 西安万寿路
        map.put("privilege_amount", Privilege.ULLINE_PRIVILEGE_AMOUNT);// 优惠金额
        map.put("ultralong_lineId", LineType.ULTRA_LONG);// 超长线ID

        map.put("zero_double", ZERO_DOUBLE);
        // map.put("privilege_insurance", PRIVILEGE_INSURANCE);
        return map;
    }

    /**
     * 提交订单并跳转到新增乘客页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/submit")
    public String orderSubmit(OrderConfirmInfoBean orderConfirmInfoBean, String refer,
                              @RequestParam(value = PRIVILEGE_ATTR, defaultValue = "false") boolean hasPrivilege, Model model,
                              @CookieValue(value = CookieName.TOKEN, defaultValue = StringConstant.BLANK) String token) {
        OrderSubmitResultBean orderSubmitResultBean = new OrderSubmitResultBean();

        String totalServicePrice = ZERO_DOUBLE;// 服务费总价
        String totalprices = ZERO_DOUBLE;// 包含服务费的支付金额总价

        // 从缓存中获取登陆用户信息
        LoginResultBean loginResultBean = tokenCacheManager.getUserFromCache(token);
        String userId = loginResultBean.getUserId();

        // 计算购票总数
        int fullticketnumber = Integer.parseInt(orderConfirmInfoBean.getFullTicketNum());
        int halfticketnumber = Integer.parseInt(orderConfirmInfoBean.getHalfTicketNum());
        int freeticketnumber = Integer.parseInt(orderConfirmInfoBean.getFreeTicketNum());
        int total = fullticketnumber + halfticketnumber + freeticketnumber;

        try {

            java.text.DecimalFormat df = new java.text.DecimalFormat(DECIMAL_PATTERN);
            totalServicePrice = df.format(Double.parseDouble(orderConfirmInfoBean.getTotalserviceprice()));
            totalprices = df.format(Double.parseDouble(orderConfirmInfoBean.getTotalprice()));

            // 设置生成订单请求参数
            orderConfirmInfoBean.setTicketNum(String.valueOf(total));
            orderConfirmInfoBean.setChannelType(ChannelType.WECHAT);
            orderConfirmInfoBean.setUserId(userId);
            // 根据FullTicketNum和HalfTicketNum，设置passengerTypeCSV
            List<String> passengerTypeList = new ArrayList<String>();
            for (int i = 0; i < fullticketnumber; i++) {
                passengerTypeList.add(PassengerType.ADULT);
            }
            for (int i = 0; i < orderConfirmInfoBean.getChildnum(); i++) {
                passengerTypeList.add(PassengerType.CHILD);
            }
            for (int i = 0; i < orderConfirmInfoBean.getSpecialnum(); i++) {
                passengerTypeList.add(PassengerType.SPECIAL);
            }
            orderConfirmInfoBean.setPassengerTypeCSV(StringUtils.collectionToCommaDelimitedString(passengerTypeList));
            if (hasPrivilege) {
                model.addAttribute(PRIVILEGE_ATTR, true);
            } else {
                model.addAttribute(PRIVILEGE_ATTR, false);
            }
            OrderSubmitParamBean orderSubmitParam = new OrderSubmitParamBean();
            beanCopier3.copy(orderConfirmInfoBean, orderSubmitParam, null);
            String hasinsurance = orderConfirmInfoBean.getHasinsurance();
            // 1表示购买保险
            if (!HASINSURANCE_ATTR.equals(hasinsurance)) {
                orderSubmitParam.setFullInsurance(ZERO_DOUBLE);
                orderSubmitParam.setHalfInsurance(ZERO_DOUBLE);
            }
            // 非当代出发站超长线标识设置为空
            if (!commonSerivce.isNCStartStation("", orderSubmitParam.getStartStationId())) {
                orderSubmitParam.setLineTypeId("");
            }

            // 调用生成订单接口
            orderSubmitResultBean = orderService.orderSubmit(orderSubmitParam);

            List<OrderSubmitBean> orderTicketList = orderSubmitResultBean.getOrderTickets();
            int fullTicketNum = 0;
            int halfTicketNum = 0;
            int freeTicketNum = 0;

            if (orderSubmitResultBean.getErrcode() == Errcode.SUCCESS) {
                final Map<String, Integer> ticketNumMap = countTicketNumFromOrderSubmitResult(orderTicketList);
                fullTicketNum = ticketNumMap.get(KEY_FULLTICKETNUM);
                halfTicketNum = ticketNumMap.get(KEY_HALFTICKETNUM);
                freeTicketNum = ticketNumMap.get(KEY_FREETICKETNUM);
                //订单票价格式化
                String price = orderTicketList.get(0).getPrice();
                orderTicketList.get(0).setPrice(df.format(Double.parseDouble(price)));
            } else {
                // 生成订单失败时List<OrderSubmitBean>为NULL，需要返回错误提示页面，提供一个返回车票查询页面的链接
                model.addAttribute("msg", orderSubmitResultBean.getErrmsg());
                model.addAttribute("gotoUri", "/trafficline/index.do");
                return "ordersubmit_tips";
            }
            orderSubmitResultBean.setFullTicketNum(fullTicketNum + "");
            orderSubmitResultBean.setHalfTicketNum(halfTicketNum + "");
            orderSubmitResultBean.setFreeTicketNum(freeTicketNum + "");
        } catch (ServiceException e) {
            LOGGER.error("调用生成订单发生异常", e);
            model.addAttribute("msg", "服务器内部错误！");
            return "error";
        }

        model.addAttribute("result", orderSubmitResultBean); // NOSONAR
        model.addAttribute("serviceprice", totalServicePrice); // NOSONAR
        model.addAttribute("totalprices", totalprices); // NOSONAR
        model.addAttribute(REFER_ATTR, refer);
        model.addAttribute(STARTSTATIONID_ATTR, orderConfirmInfoBean.getStartStationId());

        return "add_passenger"; // NOSONAR
    }

    /**
     * 从订单提交结果中统计票数
     *
     * @param orderTicketList
     *            订单车票列表
     * @return 统计票数
     */
    private Map<String, Integer> countTicketNumFromOrderSubmitResult(List<OrderSubmitBean> orderTicketList) {
        int fullTicketNum = 0, halfTicketNum = 0, freeTicketNum = 0;
        final Map<String, Integer> ticketNumMap = new HashMap<String, Integer>();

        for (OrderSubmitBean orderSubmitBean : orderTicketList) {
            if (TicketType.FULLTICKET.equals(orderSubmitBean.getTicketType())) {
                fullTicketNum++;
            } else if (TicketType.HALFTICKET.equals(orderSubmitBean.getTicketType())) {
                halfTicketNum++;
            } else if (TicketType.FREETICKET.equals(orderSubmitBean.getTicketType())) {
                freeTicketNum++;
                fullTicketNum++;
            }
        }

        ticketNumMap.put(KEY_FULLTICKETNUM, fullTicketNum);
        ticketNumMap.put(KEY_HALFTICKETNUM, halfTicketNum);
        ticketNumMap.put(KEY_FREETICKETNUM, freeTicketNum);

        return ticketNumMap;
    }
    /**
     * 订单列表页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/list")
    public String orderList(@CookieValue(value = CookieName.TOKEN, defaultValue = StringConstant.BLANK) String loginToken, String token,
                            @RequestParam(value = PAGENOW_ATTR, defaultValue = "1") int pageNow,
                            @RequestParam(value = "starting", defaultValue = "") String starting,
                            @RequestParam(value = "startCityId", defaultValue = "") String startCityId,
                            @RequestParam(value = "startStationId", defaultValue = "") String startStationId,
                            @RequestParam(value = "startStationsDisabled", defaultValue = "") String startStationsDisabled,
                            Model model) {
        UserOrderListResultBean userOrderListResultBean = new UserOrderListResultBean();
        Map<String,String> freeTicketNumMap = new HashMap<String,String>();

        if (!StringUtils.isEmpty(token)) {
            loginToken = token;
        }
        // 从缓存中获取登陆用户信息
        LoginResultBean loginResultBean = tokenCacheManager.getUserFromCache(loginToken);
        String userId = loginResultBean.getUserId();
        try {

            userOrderListResultBean = orderService.getUserOrderList(userId, PAGE_SIZE, pageNow);
            List<OrderInfoBean> orderlist = userOrderListResultBean.getOrderList();
            //计算免票数量
            for(OrderInfoBean orderInfoBean : orderlist){
                freeTicketNumMap.put(orderInfoBean.getOrderId(), String.valueOf(countFreeTicketNum(orderInfoBean)));
            }
        } catch (ServiceException e) {
            LOGGER.error("调用获取用户订单列表发生异常", e);
        }

        model.addAttribute("freeTicketNumMap", freeTicketNumMap);
        model.addAttribute("orderlist", userOrderListResultBean.getOrderList());
        model.addAttribute(PAGENOW_ATTR, pageNow);
        model.addAttribute("pageCount", userOrderListResultBean.getPageCount());
        model.addAttribute("starting", starting);
        model.addAttribute("startCityId", startCityId);
        model.addAttribute("startStationId", startStationId);
        model.addAttribute("startStationsDisabled", startStationsDisabled);

        return "order_list";
    }

    /**
     * 统计免票数量
     *
     * @param orderInfoBean
     *            订单信息
     * @return 免票数量
     */
    private int countFreeTicketNum(OrderInfoBean orderInfoBean) {
        int freeTicketNum = 0;
        for (TicketInfoBean ticketInfoBean : orderInfoBean.getTicketList()) {
            if (CarryFreeTicketFlag.CARRY.equals(ticketInfoBean.getCarryFreeTicketFlag())) {
                freeTicketNum++;
            }
        }

        return freeTicketNum;
    }
    /**
     * 订单详细信息页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/detail")
    public String orderDetail(String orderId, int pageNow, Model model) {
        OrderDetailResultBean orderDetailResultBean = new OrderDetailResultBean();
        String totalService = "";
        String totalInsurance = "";

        try {
            orderDetailResultBean = orderService.getOrderDetail(orderId);
            List<OrderTicketInfoBean> ticketList = orderDetailResultBean.getTicketList();
            String startStationId = orderDetailResultBean.getStartStationId();
            LOGGER.debug("调试日志输出-【orderDetail方法】订单状态码：{}", orderDetailResultBean.getStatusCode());
            LOGGER.debug("调试日志输出-【orderDetail方法】出发站ID：{}", startStationId);
            // 荣县西门车站和荣县南门车站和宝鸡汽车客运中心站不支持在线退票
            if (StartStationsId.RXX.equals(startStationId) || StartStationsId.RXN.equals(startStationId) || StartStationsId.ZG.equals(startStationId)
                    || StartStationsId.BJKYZ.equals(startStationId) || commonSerivce.isBYStartStation(startStationId)) {
                model.addAttribute("startStationDisableRefund", true); // NOSONAR
                LOGGER.debug("调试日志输出-【orderDetail方法】startStationDisableRefund：{}", true);
            } else {
                model.addAttribute("startStationDisableRefund", false);
                LOGGER.debug("调试日志输出-【orderDetail方法】startStationDisableRefund：{}", false);
            }

            Map<String, Object> handleTicketInfoResultMap = new HashMap<String, Object>();
            if (ticketList != null) {
                handleTicketInfoResultMap = handleOrderTicketInfo(ticketList);

                java.text.DecimalFormat df = new java.text.DecimalFormat(DECIMAL_PATTERN);
                totalService = df.format(((BigDecimal) handleTicketInfoResultMap.get(KEY_TOTALSERVICEPRICE)).doubleValue());
                totalInsurance = df.format(((BigDecimal) handleTicketInfoResultMap.get(KEY_TOTALINSURANCE)).doubleValue());

                // 计算未优惠前票价
                BigDecimal fullTicketNumBD = new BigDecimal((Integer) handleTicketInfoResultMap.get(KEY_FULLTICKETNUM));
                BigDecimal halfTicketNumBD = new BigDecimal((Integer) handleTicketInfoResultMap.get(KEY_HALFTICKETNUM));

                BigDecimal totalTicketAmount = fullTicketNumBD.multiply(new BigDecimal(orderDetailResultBean.getPrice()));
                BigDecimal totalHalfTicketAmount = halfTicketNumBD.multiply(new BigDecimal(orderDetailResultBean.getHalfPrice()));

                BigDecimal totalPrivilegeAmount = totalTicketAmount.add(totalHalfTicketAmount).add(new BigDecimal(totalInsurance))
                        .subtract(new BigDecimal(orderDetailResultBean.getTotalPrice()));
                if (totalPrivilegeAmount.compareTo(new BigDecimal(ZERO_DOUBLE)) > 0) {
                    totalPrivilegeAmount = totalPrivilegeAmount.add(new BigDecimal(totalService));
                    model.addAttribute(TOTAL_PRIVILEGE_AMOUNT_ATTR, totalPrivilegeAmount);
                }
            }

            if ((Integer) handleTicketInfoResultMap.get(KEY_PASSENGERNUM) > 0) {
                model.addAttribute(HASPASSENGERINFO_ATTR, HasTicketPassengerInfo.HAS_PASSENGERINFO);
            } else {
                model.addAttribute(HASPASSENGERINFO_ATTR, HasTicketPassengerInfo.NO_PASSENGERINFO);
            }

            boolean refundButtonEnabled = false;
            if ((Integer) handleTicketInfoResultMap.get(KEY_REFUNDNUM) > 0) {
                refundButtonEnabled = true;
                LocalDateTime now = LocalDateTime.now();
                String departureTime = String.format("%sT%s", orderDetailResultBean.getLeaveDate(), orderDetailResultBean.getLeaveTime());
                LocalDateTime leaveDatetime = LocalDateTime.parse(departureTime);
                int hours = Hours.hoursBetween(now, leaveDatetime).getHours();
                LOGGER.debug("调试日志输出-【orderDetail方法】hours：{}", hours);

                // 判断西安车站退票按钮隐藏
                if (StartStationsId.XA.equals(startStationId) || StartStationsId.XAWSL.equals(startStationId)) {
                    if (hours > 0) {
                        refundButtonEnabled = true;
                    } else {
                        refundButtonEnabled = false;
                    }

                    model.addAttribute("isShanXi", true);
                } else if (commonSerivce.isBYStartStation(startStationId)) {// 判断是否是宝运集团的车站

                    model.addAttribute("isShanXi", true);
                }
                LOGGER.debug("调试日志输出-【orderDetail方法】refundButtonEnabled：{}", refundButtonEnabled);
            } else {
                refundButtonEnabled = false;
                LOGGER.debug("调试日志输出-【orderDetail方法】refundButtonEnabled：{}", refundButtonEnabled);
            }
            model.addAttribute("refundButtonEnabled", refundButtonEnabled);

        } catch (ServiceException e) {
            LOGGER.error("调用订单详细信息发生异常", e); // NOSONAR
        }

        model.addAttribute("orderdetailresult", orderDetailResultBean);
        model.addAttribute(PAGENOW_ATTR, pageNow);
        model.addAttribute("totalService", totalService);
        model.addAttribute("totalInsurance", totalInsurance);

        return "order_detail";
    }

    /**
     * 处理订单车票信息
     * <p>
     * 分别统计不同票种的票数，合计服务费；设置车票种类名称
     *
     * @param ticketList
     *            车票列表
     * @return 处理结果
     */
    private Map<String, Object> handleOrderTicketInfo(List<OrderTicketInfoBean> ticketList) {
        Map<String, Object> handleTicketInfoResultMap = new HashMap<String, Object>();
        BigDecimal totalServicePrice = new BigDecimal(ZERO_DOUBLE);
        BigDecimal totalInsurance = new BigDecimal(ZERO_DOUBLE);
        int passengerNum = 0;
        int refundNum = 0;
        int fullTicketNum = 0;
        int halfTicketNum = 0;

        for (OrderTicketInfoBean orderTicketInfoBean : ticketList) {
            if (!StringUtils.isEmpty(orderTicketInfoBean.getFullname())) {
                passengerNum++;
            }
            LOGGER.debug("调试日志输出-【handleOrderTicketInfo方法】车票状态码：{}", orderTicketInfoBean.getTicketState());
            // 车票状态：1为已出票3为取票
            if (TicketState.TICKETED_SUCCESS.equals(orderTicketInfoBean.getTicketState())) {
                refundNum++;
            }
            LOGGER.debug("调试日志输出-【handleOrderTicketInfo方法】refundNum：{}", refundNum);
            // 设置车票类型显示名称
            if (TicketType.FULLTICKET.equals(orderTicketInfoBean.getTicketType())) {
                orderTicketInfoBean.setTicketTypeName(TicketType.CODE_NAME_MAP.get(TicketType.FULLTICKET));
                fullTicketNum++;
            } else if (TicketType.HALFTICKET.equals(orderTicketInfoBean.getTicketType())) {
                orderTicketInfoBean.setTicketTypeName(TicketType.CODE_NAME_MAP.get(TicketType.HALFTICKET));
                halfTicketNum++;
            } else if (TicketType.FREETICKET.equals(orderTicketInfoBean.getTicketType())) {
                orderTicketInfoBean.setTicketTypeName("全票");
                fullTicketNum++;
            } else if (TicketType.HALFFREETICKET.equals(orderTicketInfoBean.getTicketType())) {
                orderTicketInfoBean.setTicketTypeName("半票");
            }
            // 计算服务费总价
            totalServicePrice = totalServicePrice.add(new BigDecimal(orderTicketInfoBean.getServicePrice()));
            // 计算保费总价
            totalInsurance = totalInsurance.add(new BigDecimal(orderTicketInfoBean.getInsurance()));
        }

        handleTicketInfoResultMap.put(KEY_PASSENGERNUM, new Integer(passengerNum));
        handleTicketInfoResultMap.put(KEY_REFUNDNUM, new Integer(refundNum));
        handleTicketInfoResultMap.put(KEY_FULLTICKETNUM, new Integer(fullTicketNum));
        handleTicketInfoResultMap.put(KEY_HALFTICKETNUM, new Integer(halfTicketNum));
        handleTicketInfoResultMap.put(KEY_TOTALSERVICEPRICE, totalServicePrice);

        handleTicketInfoResultMap.put(KEY_TOTALINSURANCE, totalInsurance);

        return handleTicketInfoResultMap;
    }
    /**
     * 查询订单详情判断是否绑定乘客
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/haspassengerinfo")
    @ResponseBody
    public Map<String, String> hasPassengerInfo(String orderId, Model model) {
        OrderDetailResultBean orderDetail = new OrderDetailResultBean();
        Map<String, String> ajaxReturnMap = new HashMap<String, String>();

        try {
            orderDetail = orderService.getOrderDetail(orderId);
            List<OrderTicketInfoBean> ticketList = orderDetail.getTicketList();
            int passengerNum = 0;

            // 乘客已购车票map
            Map<String, String> passengerTicketInfoMap = new HashMap<String, String>();
            if (ticketList == null) {
                ticketList = new ArrayList<OrderTicketInfoBean>();
            }

            // 乘客已购车票信息
            PassengerTicketInfo passengerTicketInfo = new PassengerTicketInfo();
            beanCopier1.copy(orderDetail, passengerTicketInfo, null);

            for (OrderTicketInfoBean orderTicketInfo : ticketList) {
                if (!StringUtils.isEmpty(orderTicketInfo.getFullname())) {
                    beanCopier2.copy(orderTicketInfo, passengerTicketInfo, null);
                    passengerTicketInfoMap.put(pticketCacheManager.generateKey(passengerTicketInfo.toString()), orderDetail.getOrderId());

                    passengerNum++;
                }
            }

            if (passengerNum > 0) {
                ajaxReturnMap.put(HASPASSENGERINFO_ATTR, HasTicketPassengerInfo.HAS_PASSENGERINFO);

                String passengerTicketInfosCSV = StringUtils.collectionToCommaDelimitedString(passengerTicketInfoMap.entrySet());
                passengerTicketInfosCSV = URLEncoder.encode(passengerTicketInfosCSV, "UTF-8");
                ajaxReturnMap.put("ptiks", passengerTicketInfosCSV);
            } else {
                ajaxReturnMap.put(HASPASSENGERINFO_ATTR, HasTicketPassengerInfo.NO_PASSENGERINFO);
            }
        } catch (ServiceException e) {
            LOGGER.error("调用订单详情发生异常", e);
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("不支持的字符编码异常", e);
        }
        return ajaxReturnMap;
    }

    /**
     * 订单确认页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/confirm")
    public String orderConfirm(OrderConfirmInfoBean order, String ticketQueryURL, Model model,
                               @CookieValue(value = CookieName.TOKEN, defaultValue = StringConstant.BLANK) String token) {
        // 从缓存中获取登陆用户信息
        LoginResultBean loginResultBean = tokenCacheManager.getUserFromCache(token);
        order.setUserId(loginResultBean.getUserId());

        // 系统默认1张成人票
        order.setAdultnum(1);
        order.setChildnum(0);
        order.setSpecialnum(0);
        order.setFreenum(0);

        // 不收服务费的车站，服务费置零
        if (commonSerivce.isNoServicePrice(order.getStartStationId())) {
            order.setFullServicePrice(ZERO_DOUBLE);
            order.setHalfServicePrice(ZERO_DOUBLE);
        }
        // 设置测试值
        // order.setDonatedInsurance("0.00");
        // 判断是否是南充当代运业的优惠线路
        if (commonSerivce.isPrivilege(order)) {
            if (LineType.ULTRA_LONG.equals(order.getLineTypeId())) {
                model.addAttribute(PRIVILEGE_ATTR, true);
            } else {
                model.addAttribute(PRIVILEGE_ATTR, false);
                order.setFullServicePrice(ZERO_DOUBLE);
                order.setHalfServicePrice(ZERO_DOUBLE);
            }
        } else {
            model.addAttribute(PRIVILEGE_ATTR, false);
        }

        // 当代集团超长线强制选择购买保险，用户不能取消保险，为了保障乘客人身安全
        if (commonSerivce.isNCStartStation("", order.getStartStationId()) && LineType.ULTRA_LONG.equals(order.getLineTypeId())
                && (!ZERO_DOUBLE.equals(order.getDonatedInsurance()))) {
            model.addAttribute("isForceSaleInsurance", true);
        } else {
            model.addAttribute("isForceSaleInsurance", false);
        }
        // 设置测试值
        // model.addAttribute("isForceSaleInsurance", true);
        // 判断是否是西安站
        if (StartStationsId.XA.equals(order.getStartStationId()) || StartStationsId.XAWSL.equals(order.getStartStationId())) {
            model.addAttribute("isShanXi", true);
        } else if (commonSerivce.isBYStartStation(order.getStartStationId())) {
            model.addAttribute("isBaoji", true);
        }
        // TODO 测试保险说明提示
        // order.setFullInsurance("1.00");

        // 判断是否是南充当代的车站
        model.addAttribute(NCSTARTSTATION_ATTR, commonSerivce.isNCStartStation("", order.getStartStationId()));
        model.addAttribute("order", order); // NOSONAR
        model.addAttribute(TICKETQUERYURL_ATTR, ticketQueryURL);

        return "order_confirm"; // NOSONAR
    }

    /**
     * 选择乘客数量页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/passengernum")
    public String passengerNum(OrderConfirmInfoBean orderConfirmInfoBean, String ticketQueryURL, String hasPrivilege, Model model) {
        model.addAttribute(TICKETQUERYURL_ATTR, ticketQueryURL);
        model.addAttribute(PRIVILEGE_ATTR, hasPrivilege);
        model.addAttribute("orderconfirmbean", orderConfirmInfoBean);
        model.addAttribute("isSellDisabledTicket", ticketTypeService.isSellDisabledTicket(orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isSellChildTicket", ticketTypeService.isSellChildTicket(orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isSellFreeTicket", ticketTypeService.isSellFreeTicket(orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isXiAnStation", commonSerivce.isXAStartStation("", orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isZIYANGStation", StartStationsId.ZY.equals(orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isJIANYANGStation", StartStationsId.JY.equals(orderConfirmInfoBean.getStartStationId()));
        model.addAttribute("isBYStation", commonSerivce.isBYStartStation(orderConfirmInfoBean.getStartStationId()));

        return "passenger_num";
    }

    /**
     * 选择乘客类型和数量列表的确认订单页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/passengernumlist")
    public String passengerNumList(OrderConfirmInfoBean order, String ticketQueryURL, String hasPrivilege, Model model) {
        // 不收服务费的车站，服务费置零
        if (commonSerivce.isNoServicePrice(order.getStartStationId())) {
            order.setFullServicePrice(ZERO_DOUBLE);
            order.setHalfServicePrice(ZERO_DOUBLE);
        }

        model.addAttribute("order", order); // NOSONAR
        model.addAttribute(TICKETQUERYURL_ATTR, ticketQueryURL);
        model.addAttribute(PRIVILEGE_ATTR, hasPrivilege);
        // 判断是否是西安站
        if (StartStationsId.XA.equals(order.getStartStationId()) || StartStationsId.XAWSL.equals(order.getStartStationId())) {
            model.addAttribute("isShanXi", true);
        }

        model.addAttribute(NCSTARTSTATION_ATTR, order.getHasNcStartStation());
        model.addAttribute("isForceSaleInsurance", order.getIsForceSaleInsurance());
        return "order_confirm"; // NOSONAR
    }

    /**
     * 查询订单详情并跳转到新增乘客页面
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/detail2addpassenger")
    public String orderDetailToAddPassenger(String orderId, String refer, int pageNow, Model model) {
        OrderDetailResultBean orderDetailResultBean = new OrderDetailResultBean();
        String totalService = "";
        try {
            int fullTicketNum = 0;
            int halfTicketNum = 0;
            int freeTicketNum = 0;
            orderDetailResultBean = orderService.getOrderDetail(orderId);
            List<OrderTicketInfoBean> ticketList = orderDetailResultBean.getTicketList();
            BigDecimal totalAmount = new BigDecimal(ZERO_DOUBLE);

            for (OrderTicketInfoBean orderTicketInfoBean : ticketList) {
                if (TicketType.FULLTICKET.equals(orderTicketInfoBean.getTicketType())) {
                    fullTicketNum++;
                } else if (TicketType.HALFTICKET.equals(orderTicketInfoBean.getTicketType())) {
                    halfTicketNum++;
                } else if (TicketType.FREETICKET.equals(orderTicketInfoBean.getTicketType())) {
                    freeTicketNum++;
                    fullTicketNum++;
                }
                // 计算服务费总价
                BigDecimal serviceprice = new BigDecimal(orderTicketInfoBean.getServicePrice());
                BigDecimal amount = totalAmount.add(serviceprice);
                totalAmount = amount;
            }

            double total = totalAmount.doubleValue();
            java.text.DecimalFormat df = new java.text.DecimalFormat(DECIMAL_PATTERN);
            totalService = df.format(total);

            // 计算未优惠前票价
            BigDecimal fullticketnum = new BigDecimal(fullTicketNum);
            BigDecimal halfTicketnum = new BigDecimal(halfTicketNum);
            BigDecimal price = new BigDecimal(orderDetailResultBean.getPrice());
            BigDecimal halfprice = new BigDecimal(orderDetailResultBean.getHalfPrice());
            BigDecimal totalTicketAmount = fullticketnum.multiply(price);
            BigDecimal totalHalfTicketAmount = halfTicketnum.multiply(halfprice);
            BigDecimal totalPrivilegeAmount = totalTicketAmount.add(totalHalfTicketAmount).subtract(new BigDecimal(orderDetailResultBean.getTotalPrice()));
            if (totalPrivilegeAmount.compareTo(new BigDecimal(ZERO_DOUBLE)) > 0) {
                totalPrivilegeAmount = totalPrivilegeAmount.add(new BigDecimal(totalService));
                model.addAttribute(TOTAL_PRIVILEGE_AMOUNT_ATTR, totalPrivilegeAmount);
                model.addAttribute(PRIVILEGE_ATTR, true);
            } else {
                model.addAttribute(PRIVILEGE_ATTR, false);
            }

            orderDetailResultBean.setFullTicketNum(fullTicketNum + "");
            orderDetailResultBean.setHalfTicketNum(halfTicketNum + "");
            orderDetailResultBean.setFreeTicketNum(freeTicketNum + "");

        } catch (ServiceException e) {
            LOGGER.error("调用订单详细信息发生异常", e); // NOSONAR
        }
        model.addAttribute("result", orderDetailResultBean); // NOSONAR
        model.addAttribute(REFER_ATTR, refer);
        model.addAttribute(PAGENOW_ATTR, pageNow);
        model.addAttribute("serviceprice", totalService); // NOSONAR
        model.addAttribute("totalprices", orderDetailResultBean.getTotalPrice()); // NOSONAR
        model.addAttribute(STARTSTATIONID_ATTR, orderDetailResultBean.getStartStationId());
        return "add_passenger"; // NOSONAR
    }

}
